package com.sectionlistener.fragments;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import com.bitmap.ImageCache;
import com.sectionlistener.R;

import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.util.LruCache;
import android.support.v4.widget.SimpleCursorAdapter;
import android.text.TextUtils;
import android.util.Log;
import android.app.AlertDialog;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SearchView.OnCloseListener;
import android.widget.SearchView.OnQueryTextListener;
import android.widget.TextView;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
//import android.app.LoaderManager;
//import android.content.Loader;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;

public class MusicListFragment extends ListFragment 
	implements OnQueryTextListener, OnCloseListener, LoaderManager.LoaderCallbacks<Cursor> {
    /**
     * The argument key for the page number this fragment represents.
     */
    public static final String ARG_PAGE = "page";

    /**
     * The fragment's page number, which is set to the argument value for {@link #ARG_PAGE}.
     */
    private int mPageNumber;
    
    /*
     * 
     */
    private static String ROOT = "/";
    private String pathExplorer = ROOT;    
    private FilenameFilter[] mfilter;
    	
	boolean mExternalStorageAvailable = false;
//	boolean mExternalStorageWriteable = false;	
	
	// If non-null, this is the current filter the user has provided.
    String mCurFilter;
    
    // if false, it lists all files at once.
    private boolean isExplorer = false;

	
//	private SimpleCursorAdapter mAdapter;
    private MusicListAdapter mAdapter;
	private ArrayAdapter mArrayAdapter;
	
	
	OnListViewEventListener mListener;
	
	// Container activity should implement this interface
	public interface OnListViewEventListener {
		public void onTouch(int fragID);
	}

    private MusicImageWorker mMusicWorker;
    
    
    // '13. 7. 10
    // Custom listview layout couldn't be used because it failed to bind the adapter to custom_list_view.
    // Where is a solution?    
//    @Override
//    public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//        View layout = super.onCreateView(inflater, container,
//                savedInstanceState);
//        ListView lv = (ListView) layout.findViewById(android.R.id.list);
//        ViewGroup parent = (ViewGroup) lv.getParent();
//
//        // Remove ListView and add CustomView  in its place
//        int lvIndex = parent.indexOfChild(lv);
//        parent.removeViewAt(lvIndex);
//        LinearLayout mLinearLayout = (LinearLayout) inflater.inflate(
//                R.layout.list_view, container, false);
//        parent.addView(mLinearLayout, lvIndex, lv.getLayoutParams());
//     
//        return layout;
//    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // set image cache for bitmaps of thumnails
        // refer to android open source project: ImageGridActivity
        ImageCache.ImageCacheParams cacheParams =
                new ImageCache.ImageCacheParams();
        cacheParams.setMemCacheSizePercent(0.25f); // Set memory cache to 25% of app memory
        cacheParams.diskCacheEnabled = false;
        mMusicWorker = new MusicImageWorker(this.getActivity(), 96, 96);
        mMusicWorker.addImageCache(this.getFragmentManager(), cacheParams);
        mMusicWorker.setLoadingImage(R.drawable.ic_av_play);
        
        
        mPageNumber = getArguments().getInt(ARG_PAGE);
        setRetainInstance(true);
 //       initializeFileFilter();
        
        String state = Environment.getExternalStorageState();
        
        if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            mExternalStorageAvailable = true; // mExternalStorageWriteable = true;
        } else {
            mExternalStorageAvailable = false; // mExternalStorageWriteable = false;
        }
        
        if(mExternalStorageAvailable == false) {
//        	AlertDialog ad = 
        	new AlertDialog.Builder(this.getActivity()).setMessage(getResources().getText(R.string.fail_sdCard))
             .setPositiveButton(R.string.alert_ok_button,
                     new DialogInterface.OnClickListener() {
                         public void onClick(DialogInterface dialog, int whichButton) {
                             dialog.dismiss();
                         }
                     })
                     .setCancelable(false)
                     .show();
        }
        
        // setting up list view
        // Give some text to display if there is no data.  In a real
        // application this would come from a resource.
        //setEmptyText("No audio files.");

        // We have a menu item to show in action bar.
        setHasOptionsMenu(true);
        
        this.getActivity().getActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#C2DFFF")));
        this.getActivity().getActionBar().setTitle("");
        this.getActivity().getActionBar().setIcon(R.drawable.ic_navigation_refresh);

        // Create an empty adapter we will use to display the loaded data.
        mAdapter = new MusicListAdapter(getActivity(),
                R.layout.list_row, null,// null, null, 0);
                new String[] {
        			MediaStore.Audio.Media.ALBUM,
        			MediaStore.Audio.Media.TITLE,
//        			MediaStore.Audio.Media._ID},
        			MediaStore.Audio.Media.ALBUM_ID},
                new int[] {
        			R.id.row_album,
        			R.id.row_title,
//        			R.id.row_icon,
        			R.id.row_icon}, 
        			0);
        
        //setListAdapter(mAdapter);
        setListAdapter(mAdapter);
        
        getListView().setTextFilterEnabled(true);

        // Start out with a progress indicator.
        setListShown(true);
        
        // Prepare the loader.  Either re-connect with an existing one,
        // or start a new one.
        getLoaderManager().initLoader(0, null, this);
        
        // Set divider option using programming(?) (not using xml).
        getListView().setBackgroundColor(Color.WHITE);
        getListView().setDivider(new ColorDrawable(Color.WHITE));
        getListView().setDividerHeight(10);
    }

	@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
    {
//    	inflater.inflate(R.menu.music_list_menu, menu);
//    	MenuItem item = menu.findItem(R.id.search);
//    	
//        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
//            SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
//            SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
//            searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
//            searchView.setIconifiedByDefault(false);
//        }

		
        // Place on action bar item for file explorer
        MenuItem item2 = menu.add("Explorer");
        item2.setIcon(R.drawable.ic_collections_collection);
        item2.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);


		// Place an action bar item for searching.
        MenuItem searchMenu = menu.add("Search");
        searchMenu.setIcon(R.drawable.ic_action_search);
        searchMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        
 
        SearchView sv = new SearchView(getActivity());
        sv.setOnQueryTextListener(this);
        searchMenu.setActionView(sv);
        
        
//        sv.setBackgroundColor(Color.GRAY);
    }
	
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	if(item.getTitle().equals("Explorer") && !isExplorer)
    	{
    		isExplorer = true;
//    		tmp();
//    		getLoaderManager().restartLoader(0, null, this);
    		return true;
    	}
    	
    	return false;
//        switch (item.getTitle()) {
//            case R.id.Explorer:
//                onSearchRequested();
//                return true;
//            default:
//                return false;
//        }
    }
    
    private void initializeFileFilter()
    {
        // array of valid audio file extensions
        String[] audioTypes = getResources().getStringArray(R.array.audio);
        mfilter = new FilenameFilter[audioTypes.length];

        int i = 0;
        for (final String type : audioTypes) {
        	mfilter[i] = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.endsWith("." + type);
                }
            };
            i++;
        }
    }
    
    public void tmp()
    {
		File dir = new File("/system/media/audio/ringtones/");//pathExplorer);
		File[] files = dir.listFiles();
		
		List<String> mediaFiles = new ArrayList<String>();
		
		if (files != null) {
            for (File f : files) {
                for (FilenameFilter filefilter : mfilter) {
                    if(filefilter.accept(dir, f.getName())) {
                        mediaFiles.add(f.getName());
                    }
                }
            }
		}
		
		setListAdapter(new ArrayAdapter<String>(getActivity(), R.layout.list_item, mediaFiles));
    }
    
	@Override
	public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
		Uri list_uri = null;
		if(!isExplorer)
		{
			list_uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
			
//			list_uri = Uri.parse("file:///mnt/sdcard/media/audio/ringtones/");
		}
		else
		{
			File dir = new File(pathExplorer);
			File[] files = dir.listFiles();
			
			List<String> mediaFiles = new ArrayList<String>();
			
			if (files != null) {
	            for (File f : files) {
	                for (FilenameFilter filefilter : mfilter) {
	                    if(filefilter.accept(dir, f.getName())) {
	                        mediaFiles.add(f.getName());
	                    }
	                    else if(f.isDirectory())
	                    {
	                    	mediaFiles.add(f.getName());
	                    }
	                }
	            }
			}
			
//			setListAdapter(new ArrayAdapter<String>(getActivity(), R.layout.list_item, mediaFiles));

		}
		
		String selection = null;
		String[] args = null;
		
		if(mCurFilter != null)
		{
			selection = "(TITLE LIKE ? OR ARTIST LIKE ? OR ALBUM LIKE ?)";
			
			args = new String[1];
			args[0] = new String("%"+mCurFilter+"%");
			
//			String projection[] = {MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media._ID};
//			return new CursorLoader(getActivity(), list_uri, projection, selection, args, null );
		}
		
		String projection[] = {MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM_ID};
		
		return new CursorLoader(getActivity(), list_uri, projection, selection, args, null );
//		return new CursorLoader(getActivity(), list_uri, projection, null, null, null );
	}

	@Override
	public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
		// TODO Auto-generated method stub
		
		mAdapter.swapCursor(arg1);
		
		// The list should now be shown.
        if (isResumed()) {
            setListShown(true);
        } else {
            setListShownNoAnimation(true);
        }
	}

	@Override
	public void onLoaderReset(Loader<Cursor> arg0) {
		// TODO Auto-generated method stub
		
		mAdapter.swapCursor(null);		
	}

	@Override
	public boolean onClose() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onQueryTextChange(String newText) {
        // Called when the action bar search text has changed.  Update
        // the search filter, and restart the loader to do a new query
        // with this filter.
        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
        getLoaderManager().restartLoader(0, null, this);
        return true;
	}

	@Override
	public boolean onQueryTextSubmit(String query) {
		// TODO Auto-generated method stub
		return false;
	}
	
	public class MusicListAdapter extends SimpleCursorAdapter
	{
		
		
		public MusicListAdapter(Context context, int layout, Cursor c,
				String[] from, int[] to, int flags) {
			super(context, layout, c, from, to, flags);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			// super.getView(position, convertView, parent);
			View row = convertView;

			if (row == null) {
				try {
					LayoutInflater inflater = (LayoutInflater) mContext
							.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
					row = inflater.inflate(R.layout.list_row, null);// parent);
				} catch (Exception e) {
					Log.e("mList", e.getMessage(), null);
				}
			}

			TextView tvTitle = (TextView) row.findViewById(R.id.row_title);
			TextView tvAlbum = (TextView) row.findViewById(R.id.row_album);

			mCursor.moveToPosition(position);

//			int musicID = mCursor.getInt(mCursor.getColumnIndex(MediaStore.Audio.Media._ID));
			int albumID = mCursor.getInt(mCursor
					.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));

			String strTitle = mCursor.getString(mCursor
					.getColumnIndex(MediaStore.Audio.Media.TITLE));
			String strAlbum = mCursor.getString(mCursor
					.getColumnIndex(MediaStore.Audio.Media.ALBUM));

			tvTitle.setText(strTitle);
			tvAlbum.setText(strAlbum);

			// Create a cursorLoader for retrieving an thumnail of the audio
			Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
			Uri albumUri = ContentUris.withAppendedId(
					sArtworkUri, albumID);// albumID);  MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI

			ImageView iv =  (ImageView)row.findViewById(R.id.row_icon);

			mMusicWorker.loadImage(albumUri, iv);
			
			return row;
		}
	}
}